package org.example;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import org.example.service.OrderService;
import org.example.stock.StockClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;

@RestController
@RefreshScope
public class OrderController {
    // restTemplate是启动类里构建的！
    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private StockClient stockClient;

    @Autowired
    private OrderService orderService;

    @Value("${info:empty}")
    private String info;

    @GetMapping("/order/author")
    @SentinelResource("author")
    public String author(){
        return "author!";
    }

    @GetMapping("/order/hot")
    @SentinelResource(value = "hot")
    public String hot(String userId,Integer type){
        return "userId: "+userId+",type:"+type;
    }

    @GetMapping("/order/sentinel")
    @SentinelResource(value = "sentinel",defaultFallback = "defaultFallback")
    public String sentinel(@RequestParam String value) throws InterruptedException {
        switch (value){
            case "1":
                Thread.sleep(1000);
                break;
            case "2":
                int i = 1 / 0;
        }

        return "sentinel - success!";
    }
    //==================默认的fallback=======================
    public String defaultFallback(Throwable ex){
        return "failed msg = " + ex.getMessage();
    }

    // 是sentinel方法的降级方法，可以在方法逻辑中返回托底数据
    public String sentinelBlock(String value, BlockException exception){
        String message = null;
        if (exception instanceof FlowException){
            message = "流量控制！";
        }else if (exception instanceof DegradeException){
            message = "熔断控制";
        }

        return "failed  msg = " + message.toString();
    }

    // =================================熔断降级===========================
    @GetMapping("/order/circuitbreaker")
    @SentinelResource(value = "circuitbreaker")
    public String circuitbreaker(String value) throws InterruptedException {
        switch (value){
            case "1":
                Thread.sleep(1000);
                break;
            case "2":
                int i = 1 / 0;
        }

        return "circuitbreaker - success!";
    }

    @GetMapping("/order/info")
    @SentinelResource(value="info")
    public String info() {
        return info;
    }

    @GetMapping("/order/add")
    @SentinelResource(value="add")
    public String add() {
        return "add";
    }

    public String addFallback(){
        return "托底数据- 服务器正忙，请稍后再试~";
    }

    @GetMapping("/order/aaa")
    @SentinelResource(value="aaa")
    public String aaa() {
        orderService.common();
        return "aaa";
    }

    @GetMapping("/order/bbb")
    @SentinelResource(value="bbb")
    public String bbb() {
        orderService.common();
        return "bbb";
    }


    /**
     * RestTemplate测试
     * @return
     */
    @GetMapping("/order/test")
    public String test() {
        //1、 直接访问库存服务的/stock/test接口，获取数据
        String result = restTemplate.getForObject("http://stock/stock/test", String.class);

        //2、 响应数据
        return "Order Test get " + result;
    }

    /**
     * OpenFeign测试
     * @return
     */
    @GetMapping("/order/feign")
    public String feign(){
        String result= stockClient.test();
        return result;
    }

    @GetMapping("/order/gateway")
    public String gateway(HttpServletRequest request){
        return null;
    }
}